SetWindowsHookEx

Otázka od: Aleš Kresta

15. 12. 2002 18:03

Dobry den,
   mel bych jeden takovy slozitejsi dotaz: Docelt jsem se, ze funkce
SetWindowsHookEx nastavuje haky a kokud je jeji posledni
parametr(dwThreadID) nulový, pak je hak spojen se všemi vlakny. Ale toto mi
nefunguje. Udelal jsem si DLL knihovnu a exac(zdrojovy kod viz nize) a vzdy
se mi to napoji jen na ten muj exac. Pokud je aktivni jine okno, tak se nic
nedeje. Zkousel jsem i udelat si dalsi program, ktery si zjistil, jake ma
vlakno(pomoci GetCurrentThreadId) a toto cislo potom dal jako parametr
dwThreadID. Vysledek byl ten, ze to neregistrovalo stisk klaves ani v jednom
z techto dvou programu. Prosim poradte
                 Predem dekuji


DLL knihovna:

library Project2;
uses SysUtils,Classes, Windows,StdCtrls;

var
Hook: HHook;
ParentWnd: HWND;

procedure SetHook(AHook: HHook; AParentWnd: HWND); stdcall; export;
begin
Hook := AHook;
ParentWnd := AParentWnd;
end;

function KeyboardProc(nCode: Integer; WPARAM: LongInt; LPARAM: LongInt):
LResult; stdcall; export;
begin
PostMessage(ParentWnd,2000,WParam, LParam);
Result := CallNextHookEx(Hook, nCode, WParam, LParam);
end;

exports
KeyboardProc,
SetHook;

begin
end.


Exac(na formu je Tmemo pojmenovane Memo1):

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    Memo1: TMemo;
    procedure WMKlavesaDll(var Message: TMessage); message 2000;
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;


var
  Form1: TForm1;

implementation
procedure SetHook(AHook: HHook; AParentWnd: HWND); stdcall; external
'Project2.dll';
function KeyboardProc(nCode: Integer; WPARAM: wParam; LPARAM: lParam):
LResult; stdcall; external 'Project2.dll';

{$R *.dfm}

procedure TForm1.WMKlavesaDll(var Message: TMessage);
begin
Memo1.lines.add(IntToStr(Message.WParam));
end;

procedure TForm1.FormCreate(Sender: TObject);
var
Hook: HHook;
MH: THandle;
KP: Pointer;
begin
MH := GetModuleHandle('Project2.dll');
KP := GetProcAddress(MH,'KeyboardProc');
Hook := SetWindowsHookEx(WH_KEYBOARD,KP,MH,0);
SetHook(Hook,handle);
end;

end.

Odpovedá: Blazek Jaroslav

15. 12. 2002 19:02

Ahoj,

> kresta.ales@seznam.cz 14.12.02 12:47 >>>
>Dobry den, mel bych jeden takovy slozitejsi dotaz: Docelt jsem se, ze
>funkce SetWindowsHookEx nastavuje haky a kokud je jeji posledni

http://www.windev.cz/clanek.asp?stranka=key_mouse_hooks.htm


S pozdravem

Bc. Jaroslav Blazek
Access-IT Ceska Lipa
mailto:jaroslav.blazek@access-it.cz
http://www.access-it.cz
ICQ# : 133673990
+420605/813644

Odpovedá: Ondrej Kelle

15. 12. 2002 21:03

> mel bych jeden takovy slozitejsi dotaz: Docelt jsem se, ze funkce
> SetWindowsHookEx nastavuje haky a kokud je jeji posledni
> parametr(dwThreadID) nulový, pak je hak spojen se všemi
> vlakny. Ale toto mi nefunguje. Udelal jsem si DLL knihovnu a
> exac(zdrojovy kod viz nize) a vzdy se mi to napoji jen na ten muj
> exac. Pokud je aktivni jine okno, tak se nic nedeje.

[snip]

> DLL knihovna:
>
> library Project2;
> uses SysUtils,Classes, Windows,StdCtrls;
>
> var
> Hook: HHook;
> ParentWnd: HWND;
>
> procedure SetHook(AHook: HHook; AParentWnd: HWND); stdcall; export;
> begin
> Hook := AHook;
> ParentWnd := AParentWnd;
> end;

Tvoja globalna premenna ParentWnd ma danu hodnotu iba v kontexte procesu, z
ktoreho si zavolal proceduru SetHook, cize Tvojho .exe programu. V inych
procesoch je hodnota ParentWnd neinicializovana, takze procedura
KeyboardProc tu spravu posiela niekam do neznama a nie Tvojmu oknu.

V Object Pascal Language Guide je to popisane v sekcii
"Global variables in
a library".
V dokumentacii MS je to popisane v "About Dynamic-Link Libraries", sekcia
"Dynamic-Link Library Data":

Takze potrebujes, aby ta DLL bola schopna zistit si to ParentWnd z kontextu
inych procesov. Bud to urobis tak, ze si ho niekam zapises (napr. memory
mapped file alebo trebars .ini subor) pripadne si to okno mozes vyhladat
dynamicky za behu (napr. FindWindow).

HTH
TOndrej